home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UNntp.cp < prev    next >
Encoding:
Text File  |  1994-04-12  |  9.6 KB  |  453 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UNntp.cp
  3.  
  4. #include "UNntp.h"
  5. #include "URealNntp.h"
  6. #include "UFakeNntp.h"
  7. #include "UNewsAppl.h"
  8. #include "UPrefsDatabase.h"
  9. #include "UProgress.h"
  10. #include "UFatalError.h"
  11.  
  12. #include <RsrcGlobals.h>
  13.  
  14. #include <ErrorGlobals.h>
  15.  
  16. #ifndef __STDIO__
  17. #include <stdio.h>
  18. #endif
  19.  
  20. #pragma segment MyComm
  21.  
  22. #define qDebugNntpCache qDebug & 0
  23. #define qDebugConstruct qDebug & 0
  24.  
  25. TNntpCache *gNntpCache = nil;
  26.  
  27. //-----------------------------------------------------------------
  28. Boolean gUsesFakeNntp = false;
  29.  
  30. void DoUseFakeNntp()
  31. {
  32.     gUsesFakeNntp = true;
  33. }
  34.  
  35. Boolean UsesFakeNntp()
  36. {
  37.     return gUsesFakeNntp;
  38. }
  39.  
  40. //==========================================================
  41.  
  42. PNntp::PNntp()
  43. {
  44. #if qDebugConstruct
  45.     fprintf(stderr, "PNntp::PNntp() at $%lx called\n", long(this));
  46. #endif
  47.     fCurrentDotName = "";
  48.     fFirstArticleID = 1;
  49.     fLastArticleID = 0;
  50. }
  51.  
  52. PNntp::~PNntp()
  53. {
  54. #if qDebugConstruct
  55.     fprintf(stderr, "PNntp::~PNntp() at $%lx called\n", long(this));
  56. #endif
  57. }
  58.  
  59. void PNntp::INntp()
  60. {
  61. #if qDebugConstruct
  62.     fprintf(stderr, "void PNntp::INntp() at $%lx called\n", long(this));
  63. #endif
  64. }
  65.  
  66. void PNntp::SetGroup(const CStr255 &dotName, Boolean forceUpdate)
  67. {
  68.     if (forceUpdate || fCurrentDotName != dotName)
  69.     {
  70.         fCurrentDotName = dotName;
  71.         DoSetGroup(dotName);
  72.     }
  73. }
  74.         
  75. void PNntp::GetGroupInfo(long &firstArticleID, long &lastArticleID)
  76. {
  77.     firstArticleID = fFirstArticleID;
  78.     lastArticleID = fLastArticleID;
  79. }
  80.  
  81. //-----------------------------------------------------------------
  82. TNntpCache::TNntpCache()
  83. {
  84. }
  85.  
  86.  
  87. pascal void TNntpCache::Initialize()
  88. {
  89.     inherited::Initialize();
  90.     fObjectsInUseList = nil;
  91.     fIdleObjectsList = nil;
  92.     fTimeWhenCachedList = nil;
  93. }
  94.  
  95. void TNntpCache::INntpCache()
  96. {
  97.     inherited::IPeriodicAction(true);
  98.     FailInfo fi;
  99.     if (fi.Try())
  100.     {
  101.         TLongintList *lList = new TLongintList();
  102.         lList->ILongintList();
  103.         fObjectsInUseList = lList;
  104.  
  105.         lList = new TLongintList();
  106.         lList->ILongintList();
  107.         fIdleObjectsList = lList;
  108.  
  109.         lList = new TLongintList();
  110.         lList->ILongintList();
  111.         fTimeWhenCachedList = lList;
  112.  
  113.         UpdateTiming();
  114.         fi.Success();
  115.     }
  116.     else // fail
  117.     {
  118.         Free();
  119.         fi.ReSignal();
  120.     }
  121. }
  122.  
  123. pascal void TNntpCache::Free()
  124. {
  125. #if qDebugNntpCache
  126.     if (fIdleObjectsList)
  127.         fprintf(stderr, "TObjectCache::Free(), %ld idle %s's was free'd\n", fIdleObjectsList->GetSize(), GetObjectName());
  128. #endif
  129.     if (fObjectsInUseList && fIdleObjectsList && fTimeWhenCachedList)
  130.         FlushCache(); // free all cached objects
  131.     if (fObjectsInUseList && fObjectsInUseList->GetSize())
  132.     {
  133.         char msg[200];
  134.         sprintf(msg, "TObjectCache::Free(), Has %ld objects in list of in-use %s", fObjectsInUseList->GetSize(), GetObjectName());
  135.         CStr255 s(msg);
  136.         PanicExitToShell(s);
  137.     }
  138.     FreeIfObject(fObjectsInUseList); fObjectsInUseList = nil;
  139.     FreeIfObject(fIdleObjectsList); fIdleObjectsList = nil;
  140.     FreeIfObject(fTimeWhenCachedList); fTimeWhenCachedList = nil;
  141.     inherited::Free();
  142. }
  143.  
  144. long TNntpCache::CreateNewObject()
  145. {
  146.     gCurProgress->SetText(kNntpOpensConnection);
  147.     if (gUsesFakeNntp)
  148.     {
  149.         PFakeNntp *nntp = new PFakeNntp();
  150.         nntp->IFakeNntp();
  151.         return long(nntp);
  152.     }
  153.     else
  154.     {
  155.         PRealNntp *nntp = new PRealNntp();
  156.         nntp->IRealNntp(gPrefs->GetLongPrefs('SvIP'));
  157.         return long(nntp);
  158.     }
  159. }
  160.  
  161. long TNntpCache::FreeObject(long obj)
  162. {
  163.     if (obj)
  164.     {
  165.         if (gUsesFakeNntp)
  166.             delete (PFakeNntp *) obj;
  167.         else
  168.             delete (PRealNntp *) obj;
  169.     }
  170.     return nil;
  171. }
  172.  
  173. const char *TNntpCache::GetObjectName()
  174. {
  175.     if (gUsesFakeNntp)
  176.         return "PFakeNntp";
  177.     else
  178.         return "PRealNntp";
  179. }
  180.  
  181. long TNntpCache::GetNoIdleConnections()
  182. {
  183.     return fIdleObjectsList->GetSize();
  184. }
  185.  
  186. long TNntpCache::GetNoActiveConnections()
  187. {
  188.     return fObjectsInUseList->GetSize();
  189. }
  190.  
  191. void TNntpCache::UpdateTiming()
  192. {
  193.     SetSleep(gPrefs->GetLongPrefs('Tntp') / 4);
  194. }
  195.  
  196. //----------------------------------------------------
  197.  
  198. void TNntpCache::FlushCache()
  199. {
  200. #if qDebugNntpCache
  201.     fprintf(stderr, "TNntpCache::FlushCache(), %ld idle %s's was free'd\n", fIdleObjectsList->GetSize(), GetObjectName());
  202. #endif
  203. #if qDebug
  204.     if (fObjectsInUseList->GetSize())
  205.     {
  206.         fprintf(stderr, "TNntpCache::FlushCache(), There is %ld in list of USED %s!\n", fObjectsInUseList->GetSize(), GetObjectName());
  207.     }
  208. #endif
  209.     while (fIdleObjectsList->GetSize())
  210.     {
  211.         fTimeWhenCachedList->Pop();
  212.         FreeObject(fIdleObjectsList->Pop());
  213.     }
  214. }
  215.  
  216. PNntp *TNntpCache::GetNntp()
  217. {
  218.     long obj = nil;
  219.     VOLATILE(obj);
  220.     FailInfo fi;
  221.     if (fi.Try())
  222.     {
  223.         if (fIdleObjectsList->GetSize())
  224.         {
  225.             obj = fIdleObjectsList->Pop();
  226.             long idleTick = fTimeWhenCachedList->Pop();
  227. #if qDebugNntpCache
  228.             fprintf(stderr, "TNntpCache::GetObject(), popped %s at $%lx", GetObjectName(), long(obj));
  229.             fprintf(stderr, " from free list, was idle for %ld seconds\n", (TickCount() - idleTick) / 60);
  230. #endif
  231. #if qDebug
  232.             if (!IsPtrObject((PNntp*)obj))
  233.             {
  234.                 fprintf(stderr, "Object $%lx popped from free list is not object", long(obj));
  235.                 ProgramBreak(gEmptyString);
  236.             }
  237. #endif
  238.         }
  239.         else
  240.         {
  241.             obj = CreateNewObject();
  242. #if qDebugNntpCache
  243.             fprintf(stderr, "TNntpCache::GetObject(), created new %s at $%lx\n", GetObjectName(), long(obj));
  244. #endif
  245. #if qDebug
  246.             if (!IsPtrObject((PNntp*)obj))
  247.             {
  248.                 fprintf(stderr, "Created object $%lx is not object", long(obj));
  249.                 ProgramBreak(gEmptyString);
  250.             }
  251. #endif
  252.         }
  253.         fObjectsInUseList->InsertLast(obj);
  254.         fi.Success();
  255.         return (PNntp*)obj;
  256.     }
  257.     else // fail
  258.     {
  259.         obj = FreeObject(obj);
  260.         fi.ReSignal();
  261.     }
  262. }
  263.  
  264. void TNntpCache::ReturnNntp(PNntp *nntp)
  265. {
  266.     long obj = long(nntp);
  267.     if (!obj)
  268.         return;
  269.     ArrayIndex index = fObjectsInUseList->GetIdentityItemNo(obj);
  270. #if qDebug
  271.     if (!IsPtrObject(nntp))
  272.     {
  273.         ProgramBreak("Returned obj is not object");
  274.         fObjectsInUseList->Delete(obj);
  275.         return;
  276.     }
  277. #endif
  278.     if (index == kEmptyIndex)
  279.     {
  280. #if qDebug
  281.         fprintf(stderr, "TNntpCache::ReturnObject($%lx), this obj is not in list of used obj's\n", long(obj));
  282.         ProgramBreak(gEmptyString);
  283. #endif
  284.         return;
  285.     }
  286.     fObjectsInUseList->DeleteElementsAt(index, 1);
  287. #if qDebug
  288.     ArrayIndex iii = fIdleObjectsList->GetIdentityItemNo(obj);
  289.     if (iii != kEmptyIndex)
  290.     {
  291.         fprintf(stderr, "TNntpCache::ReturnObject($%lx), this obj is in list of unused obj's with index = %ld\n", long(obj), iii);
  292.         ProgramBreak(gEmptyString);
  293.         return; // don't insert it, when it's already in list
  294.     }
  295. #endif
  296. #if qDebugNntpCache
  297.     fprintf(stderr, "TNntpCache, got returned %s at $%lx\n",GetObjectName(), long(obj));
  298. #endif
  299.     if (fIdleObjectsList->GetSize() >= gPrefs->GetLongPrefs('Mntp'))
  300.     {
  301.         obj = FreeObject(obj);
  302.         return;
  303.     }
  304.     FailInfo fi;
  305.     if (fi.Try())
  306.     {
  307.         fIdleObjectsList->InsertLast(obj);
  308.         fTimeWhenCachedList->InsertLast(TickCount());
  309.         fi.Success();
  310.     }
  311.     else // fail
  312.     {
  313. #if qDebug
  314.         fprintf(stderr, "Note: could not add obj $%lx to free list (OK, just continue)", long(obj));
  315.         ProgramBreak(gEmptyString);
  316. #endif
  317.         fIdleObjectsList->Delete(obj);
  318.         obj = FreeObject(obj);
  319.         // we do NOT resignal here, as this can be called from a failure handler
  320.     }
  321. }
  322.  
  323. void TNntpCache::DiscardNntp(PNntp *nntp)
  324. {
  325.     long obj = long(nntp);
  326.     if (!obj)
  327.         return;
  328. #if qDebugNntpCache
  329.     fprintf(stderr, "TNntpCache, discarded %s at $%lx\n", GetObjectName(), long(obj));
  330. #endif
  331.     ArrayIndex index = fObjectsInUseList->GetIdentityItemNo(obj);
  332. #if qDebug
  333.     if (!IsPtrObject(nntp))
  334.     {
  335.         ProgramBreak("Discarded obj is not object");
  336.         fObjectsInUseList->Delete(obj);
  337.         return;
  338.     }
  339.     if (index == kEmptyIndex)
  340.     {
  341.         fprintf(stderr, "TNntpCache::ReturnObject($%lx), this obj is not in list of used obj's\n", long(obj));
  342.         ProgramBreak(gEmptyString);
  343.         return;
  344.     }
  345. #endif
  346.     fObjectsInUseList->DeleteElementsAt(index, 1);
  347.     FailInfo fi;
  348.     if (fi.Try())
  349.     {
  350.         obj = FreeObject(obj);
  351.         fi.Success();
  352.     }
  353.     else // fail
  354.     {
  355. #if qDebug
  356.         fprintf(stderr, "Got signal when free'ing discarded %s\n", GetObjectName());
  357.         ProgramBreak(gEmptyString);
  358. #endif
  359.     }
  360. }
  361.  
  362. void TNntpCache::DoPeriodic()
  363. {
  364.     long tc = TickCount();
  365.     long oldTick = tc - gPrefs->GetLongPrefs('Tntp') * 4 / 3;
  366.     long maxCached = gPrefs->GetLongPrefs('Mntp');
  367.     long numReleased = 0;
  368.     for (ArrayIndex index = 1; index <= fTimeWhenCachedList->GetSize(); index++)
  369.     {
  370.         long cacheTime = fTimeWhenCachedList->At(index);
  371.         if (cacheTime < oldTick || index > maxCached)
  372.         {
  373.             long obj = fIdleObjectsList->At(index);
  374. #if qDebugNntpCache
  375.             fprintf(stderr, "TNntpCache, Free's expired %s at $%lx, idle time = %ld seconds\n",
  376.                 GetObjectName(), long(obj), (tc - cacheTime) / 60);
  377.             if (!IsPtrObject((PNntp*)obj))
  378.                 ProgramBreak("The obj is not object");
  379. #endif
  380.             fIdleObjectsList->DeleteElementsAt(index, 1);
  381.             fTimeWhenCachedList->DeleteElementsAt(index, 1);
  382.             FailInfo fi;
  383.             if (fi.Try())
  384.             {
  385.                 obj = FreeObject(obj);
  386.                 fi.Success();
  387.             }
  388.             else // fail
  389.             {
  390. #if qDebug
  391.                 ProgramBreak("Failed in free of expired cached object");
  392. #endif
  393.             }
  394.             numReleased++;
  395.         }
  396.     } // for
  397. #if qDebug
  398.     fprintf(stderr, "Released %ld NNTP connections\n", numReleased);
  399. #endif
  400. }
  401.  
  402. Boolean TNntpCache::NeedTime()
  403. {
  404.     if (fIdleObjectsList->fSize > gPrefs->GetLongPrefs('Mntp'))
  405.         return true;
  406.     long tc = TickCount();
  407.     long oldTick = tc - gPrefs->GetLongPrefs('Tntp') * 4 / 3;
  408.     for (ArrayIndex index = 1; index <= fTimeWhenCachedList->fSize; index++)
  409.     {
  410.         long cacheTime = fTimeWhenCachedList->At(index);
  411.         if (cacheTime < oldTick)
  412.             return true;
  413.     }
  414.     return false;    
  415. }
  416.  
  417. Boolean TNntpCache::SkipFirstCheckAfterWakeUp()
  418. {
  419.     return true;
  420. }
  421.  
  422. const char *TNntpCache::GetDebugDescription()
  423. {
  424.     return "TNntpCache";
  425. }
  426.  
  427.  
  428. //.................................................................
  429.  
  430. void InitUNntp()
  431. {
  432. #if qDebug
  433.     if (gNntpCache)
  434.         ProgramBreak("InitUNntp called twice");
  435. #endif
  436.     TNntpCache *nc = new TNntpCache();
  437.     nc->INntpCache();
  438.     gNntpCache = nc;
  439. }
  440.  
  441. void CloseDownUNntp()
  442. {
  443. #if qDebug
  444.     if (!gNntpCache)
  445.         fprintf(stderr, "gNntpCache is nil in CloseDownUNntp()\n");
  446. #endif
  447.     if (gNntpCache)
  448.     {
  449.         gNntpCache->Close();
  450.         FreeIfObject(gNntpCache); gNntpCache = nil;
  451.     }
  452. }
  453.